class MessageController < ApplicationController
  layout "message"
  
  before_filter :authorize, :except => [:public, :show, :user]
  
  def index
    if session[:user_name].nil?
      redirect_to(:controller => :home, :action => "index")
    else
      users = User.find(:all, :conditions => ["name='#{session[:user_name]}'"])
      @user = users[0]
      @is_myself = true
      @page_title = "Microblog_#{@user.display_name}"
      get_paged_message
    end
  end
  
  def at
    @user = get_current_user(session[:user_name])
    @messages = get_at_message(@user.id)
    @page_title = "#{@user.display_name}'s @ replies_Microblog"
    render(:controller => :home, :action => :index)
  end
  
  def user
    users = User.find(:all, :conditions => ["id='#{params[:id]}'"])
    @user = users[0]
    # Judge if the user is himself. if so, redirect to home.
    # If page > 0, do nomal message list.
    # I didn't add any paging processing in index method,
    # I can noly deal with it this way.
    if !(params[:page].to_i > 0) && @user.name == session[:user_name]
      redirect_to(:controller => :message, :action => "index")
    else
      get_paged_message
      @page_title = "Microblog_#{@user.display_name}"
      # Is friend judgement
      user = get_current_user(session[:user_name])
      friend_ids = []
      Follower.get_friend_list(user.id).each do |f|
        friend_ids << f.user_id
      end
      @is_existing_friend = false
      @is_existing_friend = true if friend_ids.include?(params[:id].to_i)
      # end of friend judgement
      render(:action => "index")
    end
  end
  
  
  def public
    @page_title = "Microblog_Public timeline"
    @messages = Message.find(:all, :limit => 20, :order => "post_at DESC")
  end
  
  def post
    @users = User.find(:all, :conditions => ["name='#{session[:user_name]}'"])
    @users.each do |user|
      @message = Message.new
      @message.user_id = user.id
      text = text_process(params[:content].nil? ? '' : params[:content])
      if text
        @message.content = text
        @message.post_at = Time.now
        unless @message.save
          flash[:notice] = "Post failed!"
        end
      else
        flash[:notice] = "Please input some text."
      end
      redirect_to(:controller => :home, :action => "index")
    end
  end
  
  def delete
    msg = Message.find(params[:id])
    user = User.find(msg.user_id)
    unless session[:user_name] == user.name
      # If unauthorized user attempt to delete message
      # Simply redirect to home page. No error message displayed.
      redirect_to(:controller => :home, :action => "index")
    else
      begin
        msg.destroy
        flash[:notice] = "Message deleted successfully."
      rescue Exception => e
        flash[:notice] = e.message
      end
      uri = session[:ori_uri]
      session[:ori_uri] = nil
      redirect_to( uri || {:controller => :home, :action => "index"})
    end
  end
  
  def show
    # Put the controller in the wrong place, so use some dirty way to solve it.
    # This should be resolved in later revision.
    @narrowlook = true
    @message = Message.find(params[:id])
    @user = User.find(@message.user_id)
    @page_title = "#{@user.display_name}'s Message_Microblog"
  end
  
  private

  def text_process(text)
    text.strip!
    #get rid of all the special chars
    text.gsub!(/[\n\r\s\t]+/mu," ")
    if text == ""
      return false
    else
      # use jtext to solve the dirty problem.
      # I don't know if there is a slice method for
      # unicode.
      count = 0
      new_text = ''
      text.each_char do |mb|
        new_text += mb
        count += 1
        break if count >= 140
      end
      # add @ processing and url trim here.
      new_text = at_detect(html_escape(new_text))
      return new_text
    end
  end
  
  def at_detect(text)
    # There will be a fatal error, if two users with the same nick_name
    # So simply ignore the @reply while encounter this situation.
    regex = /^@(\w+)\s/ui
    unless text =~ regex
      return text
    else
      name = $1.to_s
      users = User.find(:all, :conditions => "nick_name='#{name}'")
      if users.length == 1
        user = users[0]
        text.sub!(name, "<a href=\"/message/user/#{user.id}\">#{name}</a>")
        return text
      else
        return text
      end
    end
  end
  
  def html_escape(text)
    text.gsub!("&", "&amp;")
    text.gsub!("<", "&lt;")
    text.gsub!(">", "&gt;")
    text
  end

  def get_message_count(id)
    Message.find(:all, :conditions => ["user_id='#{id}'"]).length
  end
  
  def get_paged_message
    @message_count = get_message_count(@user.id)
    @page_count = (@message_count / 20.0).ceil
    if @message_count > 20
      @paged = true
    end
    @page = params[:page].nil? ? 1 : params[:page].to_i
    @messages = Message.find(:all, :conditions => ["user_id='#{@user.id}'"],
      :order => "post_at DESC", :limit => 20, :offset => ((@page - 1) * 20))
  end
  
  def get_current_user(name)
    users = User.find(:all, :conditions => ["name='#{name}'"])
    users[0]
  end
  
  def get_at_count(id)
    Message.find(:all, :conditions => ["user_id='#{id}' AND content LIKE ?", '@<a%']).length
  end
  
  def get_at_message(id)
    message_count = get_at_count(id)
    page_count = (message_count / 20.0).ceil
    if message_count > 20
      @paged = true
    end
    @page = params[:page].nil? ? 1 : params[:page].to_i
    messages = Message.find(:all, :conditions => ["user_id='#{id}' AND content LIKE ?", '@<a%'],
      :order => "post_at DESC", :limit => 20, :offset => ((@page - 1) * 20))
    messages
  end
    
end
